package com.cqw.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cqw.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-07-07 09:53
 * @Description: RestTemplate
 */
@Slf4j
public class HttpUtil {


    public static String doGetRequest(RestTemplate restTemplate, String url, Map<String, Object> params, Map<String, String> headerMap) {
        return doGetResult(restTemplate, url, params, headerMap, "data");
    }

    public static String doGetResult(RestTemplate restTemplate, String url, Map<String, Object> params, Map<String, String> headerMap, String response) {
        long startTime = System.currentTimeMillis();

        //拼接参数
        StringBuilder sb = new StringBuilder(url);
        if (MapUtil.isNotEmpty(params)) {
            sb.append("?");
            for (Map.Entry<String, Object> enter : params.entrySet()) {
                sb.append(enter.getKey()).append("=").append(enter.getValue()).append("&");
            }
        }

        if (MapUtil.isNotEmpty(params)) {
            sb.deleteCharAt(sb.length() - 1);
        }

        url = sb.toString();

        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        if (MapUtil.isNotEmpty(headerMap)) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                headers.add(entry.getKey(), entry.getValue());
            }
        }

        HttpEntity<byte[]> httpEntity = new HttpEntity<>(headers);

        ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, byte[].class);
        byte[] responseDate = responseEntity.getBody();

        String responseBody = "";

        if (responseDate != null && responseDate.length > 0) {
            responseBody = new String(responseDate, StandardCharsets.UTF_8);
        }

        HttpStatus statusCode = responseEntity.getStatusCode();

        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            String msg = String.format("url:%s,param:%s,statusCode:%d,response:%s", url, params, statusCode.value(), responseBody);
            log.error(msg);
            throw new HttpServerErrorException(responseEntity.getStatusCode());
        }

        log.debug("请求接口：{},耗时：{}，返回：{}", url, (System.currentTimeMillis() - startTime), responseDate);

        JSONObject pa = JSONObject.parseObject(responseBody);

        Integer code = pa.getInteger("code");
        if (code.equals(200)) {
            return pa.getString(response);
        } else {
            log.error("请求接口失败:{},返回：{}", url, responseDate);
            throw new CommonException("接口请求失败" + url);
        }
    }


    public static String doPostRequest(RestTemplate restTemplate, String url, Map<String, Object> params, Map<String, String> headersMap, String response) {
        return doPostResult(restTemplate, url, params, headersMap, response);
    }

    public static String doPostResult(RestTemplate restTemplate, String url, Map<String, Object> params, Map<String, String> headersMap, String response) {
        long startTime = System.currentTimeMillis();

        //拼接参数
        if (MapUtil.isNotEmpty(params)) {
            StringBuilder sb = new StringBuilder(url);
            sb.append("?");
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            url = sb.deleteCharAt(sb.length() - 1).toString();
        }

        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        if (MapUtil.isNotEmpty(headersMap)) {
            for (Map.Entry<String, String> entry : headersMap.entrySet()) {
                headers.add(entry.getKey(), entry.getValue());
            }
        }

        HttpEntity<byte[]> httpEntity = new HttpEntity<>(headers);

        //调用接口
        ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, byte[].class);

        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            log.error("接口:{}调用失败,返回：{}", url, JSON.toJSONString(responseEntity));
            throw new HttpServerErrorException(responseEntity.getStatusCode());
        }

        byte[] responseEntityBody = responseEntity.getBody();

        String responseBody = "";
        if (responseEntityBody != null && responseEntityBody.length > 0) {
            responseBody = new String(responseEntityBody, StandardCharsets.UTF_8);
        }

        JSONObject pa = JSONObject.parseObject(responseBody);

        Integer code = pa.getInteger("code");
        if (code.equals(200)) {
            return pa.getString(response);
        } else {
            log.error("接口:{}调用失败,返回：{}", url, JSON.toJSONString(responseEntityBody));
            throw new CommonException("接口调用失败：" + url);
        }
    }


    /**
     * @param restTemplate
     * @param url
     * @param method
     * @param responseBodyType
     * @param responseBody
     * @param headerMap
     * @param <T>
     * @return
     */
    public static <T> T exchangeByJson(RestTemplate restTemplate, String url, HttpMethod method, ParameterizedTypeReference<T> responseBodyType, String responseBody, Map<String, String> headerMap) {
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        if (MapUtil.isNotEmpty(headerMap)) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                headers.add(entry.getKey(), entry.getValue());
            }
        }

        try {
            HttpEntity<String> entity = new HttpEntity<>(responseBody, headers);

            ResponseEntity<T> responseEntity = restTemplate.exchange(url, method, entity, responseBodyType);
            log.info("");
            return responseEntity.getBody();
        } catch (RestClientException e) {
            log.error("接口" + url + "调用失败", e);
            return null;
        }
    }


}
